<?php

namespace app\common\model\xilumarket;

use app\common\library\Auth;
use app\common\model\User;
use think\Db;
use think\Exception;
use think\exception\PDOException;
use think\Model;
use think\model\Pivot;
use traits\model\SoftDelete;
use function fast\array_get;

class Aftersale extends Pivot
{

    use SoftDelete;

    #售后状态
    const AFTERSALE_STATUS_CANCEL   = '-2';  // 取消
    const AFTERSALE_STATUS_REFUSE   = '-1';  // 拒绝
    const AFTERSALE_STATUS_APPLY    = '0';    //用户申请
    const AFTERSALE_STATUS_NOOPER   = '1';   //同意申请
    const AFTERSALE_STATUS_FREIGHT  = '2';   //物流提交，等待退款
    const AFTERSALE_STATUS_REFUND   = '3';   //退款成功
    const AFTERSALE_STATUS_FINISH   = '4';   //售后完成

    // 表名
    protected $name = 'xilumarket_aftersale';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';

    // 追加属性
    protected $append = [
        'express_type_text',
        'type_text',
        'images_text',
        'createtime_text',
    ];

    public function getImagesTextAttr($value,$data){
        $images = [];
        $value = isset($data['images'])?$data['images']:'';
        if($value && is_string($value)){
            $images_array = explode(',',$value);
            foreach ($images_array as $image){
                $images[] = cdnurl($image,true);
            }
        }
        return $images;
    }

    public function getCreatetimeTextAttr($value,$data){
        $value = $value ? $value : (isset($data['createtime']) ? $data['createtime'] : '');
        return is_numeric($value) ? date("Y.m.d H:i", $value) : $value;
    }
    
    public function getExpressTypeList()
    {
        return ['0' => __('未收到货'), '1' => __('已收到货')];
    }

    public function getTypeList()
    {
        return ['0' => __('我要退款'), '1' => __('退货退款'), '2' => __('换货')];
    }

    public function getStateList()
    {
        return ['0' => __('State 0'), '1' => __('State 1'), '2' => __('State 2'), '3' => __('State 3'), '-2' => __('State -2'), '-1' => __('State -1')];
    }

    public function getStatusList()
    {
        return ['normal' => __('Normal'), 'hidden' => __('Hidden')];
    }


    public function getExpressTypeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['express_type']) ? $data['express_type'] : '');
        $list = $this->getExpressTypeList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getTypeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['type']) ? $data['type'] : '');
        $list = $this->getTypeList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getStateTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['state']) ? $data['state'] : '');
        $list = $this->getStateList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getAgreetimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['agreetime']) ? $data['agreetime'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getReturntimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['returntime']) ? $data['returntime'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getRejecttimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['rejecttime']) ? $data['rejecttime'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getClosingtimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['closingtime']) ? $data['closingtime'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getCompletetimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['completetime']) ? $data['completetime'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getStatusTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
        $list = $this->getStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    /**
     * 售后订单信息
     */
    public function user(){
        return $this->hasOne(User::class,'id','user_id',[],'LEFT')->setEagerlyType(0);
    }

    /**
     * 售后订单信息
     */
    public function orderGoods(){
        return $this->belongsTo('OrderGoods','order_goods_id','id',[],'LEFT')->setEagerlyType(0);
    }

    /**
     * 售后
     */
    public function aftersaleLog(){
        return $this->hasMany('AftersaleLog','aftersale_id')->order('id','desc');
    }



    /**
     * 数量
     * @param $where
     * @return int|string
     * @throws \think\Exception
     */
    public static function get_count($where){
        return self::where($where)->count();
    }

    /**
     * 售后列表
     * @param array $param
     * @return \think\Paginator
     * @throws \think\exception\DbException
     */
    public static function lists($param)
    {
        $where['user_id'] = (Auth::instance())->id;

        $state = !empty($param['state']) ? $param['state'] : 9999;

        switch ($state){
            case -2:
                //取消
                $where['state'] = $state;
                $order = 'canceltime desc';
                break;
            case -1:
                //拒绝
                $where['state'] = $state;
                $order = 'rejecttime desc';
                break;
            case 0:
                //申请
                $where['state'] = $state;
                $order = 'createtime desc';
                break;
            case 1:
                //同意（待上传物流）
                $where['state'] = $state;
                $order = 'agreetime desc';
                break;
            case 2:
                //上传物流，待审核
                $where['state'] = $state;
                $order = 'updatetime desc';
                break;
            case 3:
                //成功退款
                $where['state'] = $state;
                $order = 'refundtime desc';
                break;
            default:
                //全部
                $order = 'id desc';
                break;
        }

        $limit = $param['pagesize'] ?? 10;
        $list = self::with(['orderGoods'])
            ->where($where)
            ->order($order)
            ->paginate($limit);
        return $list;
    }

    /**
     * 售后提交
     */
    public static function add($params,$user){
        $validator = new \app\common\validate\xilumarket\Aftersale();
        if(!$validator->check($params)){
            throw new Exception($validator->getError());
        }
        $order_id = array_get($params,'order_id');
        $order_product_id = array_get($params,'order_product_id');
        $aftersale = self::where('order_id',$order_id)
            ->where('order_product_id',$order_product_id)
            ->whereIn('state',[
                self::AFTERSALE_STATUS_APPLY,
                self::AFTERSALE_STATUS_NOOPER,
                self::AFTERSALE_STATUS_FREIGHT,
                self::AFTERSALE_STATUS_REFUND
            ])
            ->find();
        if($aftersale){
            throw new Exception("商品已退款或在申请中");
        }
        $order = Order::get($order_id);
        if(in_array($order->refund_status,[1,2])){
            throw new Exception("商品已退款或在申请中");
        }
        $params['images'] = $params['images'] ? (is_array($params['images']) ? implode(',',$params['images']) : $params['images']) :'';
        $params['order_no'] = "R".date("YmdHis").mt_rand(1000,9999);
        $params['state'] = '0';
        $params['user_id'] = $user->id;
        $aftersale = self::create($params);
        Db::startTrans();
        try {
            #订单商品的售后状态更改
            $order->refund_status = 1; //退款申请中
            $order->refund_time = time();
            $order->save();
            // 增加售后单变动记录
            AftersaleLog::operate_add($order, $aftersale, $user, 'user', [
                'title' => '买家申请售后退款',
                'description' => '买家申请售后退款，等待卖家同意',
                'images' =>  $params['images']
            ]);
        }catch (Exception|PDOException $e){
            Db::rollback();
            throw $e;
        }
        Db::commit();
        return $aftersale;

    }


    /**
     * 售后物流
     */
    public static function express($params,$user){
        $aftersale_id = array_get($params,'aftersale_id');
        $aftersale = $aftersale_id?self::get($aftersale_id):null;
        if(!$aftersale){
            throw new Exception("售后订单不存在");
        }
        if($aftersale->type == '0'){
            throw new Exception("仅退款无需上传物流");
        }
        if($aftersale->state != '1'){
            throw new Exception("售后状态不可上传物流");
        }
        $order = Order::get($aftersale->order_id);
        $express_company_id = array_get($params,'express_company_id');
        $express_company = $express_company_id?ExpressCompany::field('id,name,code')->where('id',$express_company_id)->find() : null;
        if(!$express_company){
            throw new Exception("物流公司不存在");
        }
        if(!$express_no= array_get($params,'express_no')){
            throw new Exception("物流单号错误");
        }
        Db::startTrans();
        try {
            $aftersale->save([
                'state'         =>  '2',
                'express_name'  =>  $express_company['name'],
                'express_no'    =>  $params['express_no'],
            ]);
            // 增加售后单变动记录
            AftersaleLog::operate_add($order, $aftersale, $user, 'user', [
                'title' => '买家售后物流单号提交',
                'description' => '买家物流单号已提交，等待卖家同意',
                'images' => []
            ]);
        }catch (Exception|PDOException $e){
            Db::rollback();
            throw $e;
        }
        Db::commit();
        return $aftersale;

    }
}
